package yxy.game.pm2.module.plainsarena;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.plainsarena;
import yxy.cherry.data.function.Function;
import yxy.game.pm2.bean.Format;
import yxy.game.pm2.bean.Format.FormatType;
import yxy.game.pm2.bean.Hero;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.module.hero.FormatHandle;
import yxy.game.pm2.module.player.FunctionHandle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;

//中原擂台，用户参赛模块
public class PlainsArenaPlayerModule extends PlayerModule {
	// bean===========================================================================

	private String code = "";// 比赛代号 判断不同的代号更新

	private int level;// 段位
	private int wins;// 胜场数
	private int usedFormatTimes = 0; //当天已用的布阵次数
	private int usedFreeTimes = 0; //当天已用的免费挑战次数
	private int buyTimes = 0; //剩余的可用的挑战次数（购买）
	private int buyAmount = 0; //活动期间购买的总挑战次数；前3次购买花费50元宝，3-5次花费100元宝，5次之后花费200元宝
	private String dateTime = ""; //日期 （如果不是当天值，则重置每天的免费挑战次数、调整布局次数等）
	private int isFormatInit = 0; //是否已经调整过阵容

	private LinkedList<String> oppos = new LinkedList<>();// 对手池
	private ArrayList<String> box = new ArrayList<>();// 已经领取的宝箱
	private ArrayList<String> levelBox = new ArrayList<>();// 已经领取的段位奖励

	private ArrayList<Format> format = new ArrayList<>();// 阵容

	private boolean skip;

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public int getWins() {
		return wins;
	}

	public void setWins(int wins) {
		this.wins = wins;
	}

	public LinkedList<String> getOppos() {
		return oppos;
	}

	public void setOppos(LinkedList<String> oppos) {
		this.oppos = oppos;
	}

	public ArrayList<String> getBox() {
		return box;
	}

	public void setBox(ArrayList<String> box) {
		this.box = box;
	}

	public ArrayList<String> getLevelBox() {
		return levelBox;
	}

	public void setLevelBox(ArrayList<String> levelBox) {
		this.levelBox = levelBox;
	}

	public ArrayList<Format> getFormat() {
		return format;
	}

	public void setFormat(ArrayList<Format> format) {
		this.format = format;
	}

	public boolean isSkip() {
		return skip;
	}

	public void setSkip(boolean skip) {
		this.skip = skip;
	}

	public int getUsedFormatTimes() {
		return usedFormatTimes;
	}

	public void setUsedFormatTimes(int usedFormatTimes) {
		this.usedFormatTimes = usedFormatTimes;
	}

	public int getUsedFreeTimes() {
		return usedFreeTimes;
	}

	public void setUsedFreeTimes(int usedFreeTimes) {
		this.usedFreeTimes = usedFreeTimes;
	}

	public int getBuyTimes() {
		return buyTimes;
	}

	public void setBuyTimes(int buyTimes) {
		this.buyTimes = buyTimes;
	}

	public int getBuyAmount() {
		return buyAmount;
	}

	public void setBuyAmount(int buyAmount) {
		this.buyAmount = buyAmount;
	}

	public String getDateTime() {
		return dateTime;
	}

	public void setDateTime(String dateTime) {
		this.dateTime = dateTime;
	}

	public int getIsFormatInit() {
		return isFormatInit;
	}

	public void setIsFormatInit(int isFormatInit) {
		this.isFormatInit = isFormatInit;
	}
	// func===========================================================================

	private void update() {
		PlayerBean playerBean = PlayerBean.get(getPlayerCode());
		ServerBean serverBean = ServerBean.get(playerBean.getServerId());
		AreaBean areaBean = AreaBean.get(serverBean.getAreaId());

		PlainsArenaModule module = PlainsArenaModule.get(areaBean.getGroupId());
		if (module.getCode() == null) {
			return;
		}
		if (getCode() == null || !getCode().equals(module.getCode())) { //活动开启时间对比
			try {
				if (tryLock()) {
					setCode(module.getCode());
					setLevel(1);
					setWins(0);
					getOppos().clear();
					getBox().clear();
					getLevelBox().clear();
					set();
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				unlock();
			}
		}

		//每天重置数据
		String now = DateTime.now().toString(DateTimeFormat.forPattern("yyyyMMdd")).toString(); //今天
		if (dateTime == null || dateTime.equals("") || !dateTime.equals(now)) {
			//dateTime未初始化或者不是同一天，则重置当天的相关数据
			dateTime = DateTime.now().toString(DateTimeFormat.forPattern("yyyyMMdd")).toString();
			usedFormatTimes = 0;
			usedFreeTimes = 0;
			buyAmount = 0;
			set();
		}
	}

	// redis==========================================================================

	private static String key(String playerCode) {
		return String.format("PLAYER:%s:MODULE:PLAINSARENA", playerCode);
	}

	public void set() {
		try {
			setv(key(getPlayerCode()), this);
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}

	static public PlainsArenaPlayerModule get(String playerCode) {
		try {
			PlainsArenaPlayerModule module = getv(key(playerCode));
			if (module == null) {
				module = MySQLCacheDAO.getV(key(playerCode), PlainsArenaPlayerModule.class);
				if(module != null){module.set();}//把数据同步到redis
			}

			if (module == null) {
			    //兼容旧的不去判断条件,直接前端控制是否开放这个活动
//				if (!new FunctionHandle().check(Function.逐鹿中原, playerCode)) {
//					return null;
//				}
				module = create(playerCode);
			}
			module.update();
			return module;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	static private PlainsArenaPlayerModule create(String playerCode) {
		Format format = new FormatHandle().get(playerCode, FormatType.普通);

		PlainsArenaPlayerModule module = new PlainsArenaPlayerModule();
		module.setPlayerCode(playerCode);
		module.getFormat().add(format);
		module.getFormat().add(new Format());
		module.getFormat().add(new Format());
		module.timeline();
		//module.setDateTime(DateTime.now().toString(DateTimeFormat.forPattern("yyyyMMdd")).toString());
		module.set();
		return module;
	}

	//存储到数据库的方法
	public static void saveToDB(String playerCode) {
		try {
			String key = key(playerCode);
			if (touchBucket(key).isExists()) {
				PlainsArenaPlayerModule plainsArenaPlayerModule = getv(key(playerCode));
				if(plainsArenaPlayerModule != null)MySQLCacheDAO.setV(key, plainsArenaPlayerModule);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	//从redis移走数据的操作
	public static void removeAllFromRedis(String playerCode) {
		try {
			touchBucket(key(playerCode)).delete();
		} catch (RedisException e) {
			e.printStackTrace();
		}
	}

	//可用的挑战次数
	public static int getTimes (PlainsArenaPlayerModule playerModule) {
		plainsarena config = DataCenter.getData(String.valueOf(playerModule.getLevel()), plainsarena.class); //配置表
		int times = config.getFreetimes() - playerModule.getUsedFreeTimes() + playerModule.getBuyTimes();
		return times > 0 ? times : 0;
	}

	//可用的阵容调整次数
	public static int getFormatTimes (PlainsArenaPlayerModule playerModule) {
		plainsarena config = DataCenter.getData(String.valueOf(playerModule.getLevel()), plainsarena.class); //配置表
		int times = config.getFormattimes() - playerModule.getUsedFormatTimes();
		return times > 0 ? times : 0;
	}

	//使用挑战次数
	public static void useTimes (PlainsArenaPlayerModule playerModule, int num) {
		try {
			if (playerModule.tryLock()) {
				plainsarena config = DataCenter.getData(String.valueOf(playerModule.getLevel()), plainsarena.class); //配置表
				int freeTimes = config.getFreetimes(); //免费挑战次数

				if (playerModule.getUsedFreeTimes() < freeTimes) {
					//先使用免费次数
					playerModule.usedFreeTimes += num;
				} else {
					playerModule.buyTimes -= num; //购买的剩余次数
				}
				playerModule.set();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			playerModule.unlock();
		}
	}

	//挑战次数购买单价
	public static int getBuyTimesPrice (PlainsArenaPlayerModule playerModule) {
		//每天有免费5次机会，5次机会用完后，需要花费元宝购买（前3次购买花费50元宝，3-5次花费100元宝，5次之后花费200元宝）。
		if (playerModule.buyAmount < 3) return 50;
		if (playerModule.buyAmount >= 3 && playerModule.buyAmount < 5) return 100;
		return 200;
	}

	//初始化队伍
	public static void initFormats (PlainsArenaPlayerModule playerModule) {
		if (playerModule.getIsFormatInit() == 1) return;
		plainsarena config = DataCenter.getData(String.valueOf(playerModule.getLevel()), plainsarena.class); //配置表
		if (playerModule.getFormat() != null && playerModule.getFormat().size() == config.getPvptype()) return; //已经有队伍

		playerModule.getFormat().clear();

		Collection<Hero> heros = Hero.all(playerModule.getPlayerCode()).values();
		ArrayList<Hero> list = new ArrayList<>();
		heros.forEach(hero -> {
			list.add(hero);
		});

		for (int i = 1; i <= config.getPvptype(); i++) {
			if (list.size() < i) break;
			Hero hero = list.get(i - 1);
			Format format = new Format();
			if (hero != null) {
				format.setFu(hero.getCode());
			}
			playerModule.getFormat().add(format);
		}
		playerModule.set();
	}

	// lock==========================================================================

	@Override
	public String lockKey() {
		return String.format("lock:%s", key(getPlayerCode()));
	}

}
